package org.awa.demo.opencv.gltf.handler;

import lombok.extern.slf4j.Slf4j;
import org.awa.demo.opencv.bean.gltf.FaceItemDto;
import org.awa.demo.opencv.bean.gltf.GridItemDto;
import org.awa.demo.opencv.bean.gltf.PointItemDto;
import org.awa.demo.opencv.bean.gltf.PrimitiveBean;
import org.awa.demo.opencv.gltf.Constant;
import org.awa.demo.opencv.gltf.SoundUtil;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class RectangleAnalysis {

    public FaceItemDto getFace(PrimitiveBean primitiveBean, IRectangleHandler rectangleHandler) {
        log.info("cal face name: "+primitiveBean.getName());

        //统一先X轴，X轴为宽，另一个（Y轴或Z轴为高）。此处用于为基于blender坐标系来说的。
        // 实际就是假设第一个线  point[0,1]为width所在的线，point[1，2]为height所在的线，而pont[0]为起始点

        FaceItemDto faceItemDto = new FaceItemDto();
        faceItemDto.setName(primitiveBean.getName());
        faceItemDto.setHandleClass(rectangleHandler == null ? "null" : rectangleHandler.getClass().getSimpleName());
        faceItemDto.setGltfPointList(getPointList(primitiveBean.getPointList(),false));
        faceItemDto.setBlenderPointList(getPointList(primitiveBean.getBlenderPointList(),false));

        if(rectangleHandler != null){
            List<float[]> rectanglePointList = rectangleHandler.getRectanglePointList(primitiveBean.getBlenderPointList());
            faceItemDto.setScopeList(getPointList(rectanglePointList,true));
            int widthSize = getWidthSize(rectanglePointList.get(0),rectanglePointList.get(1));
            int heightSize = getWidthSize(rectanglePointList.get(1),rectanglePointList.get(2));
            faceItemDto.setWidthSize(widthSize);
            List<float[]> gridList = rectangleHandler.getGridObject(rectanglePointList,widthSize,heightSize);
            List<GridItemDto> gridItemList = new ArrayList<>();
            for (int i = 0; i < gridList.size(); i++) {
                GridItemDto gridItemDto = new GridItemDto();
                gridItemDto.setIndex(i);

                float[] gridPoint = gridList.get(i);
                gridItemDto.setPointCrs(SoundUtil.toGltfCrs(gridPoint));
                log.info("trans crs: "+ SoundUtil.toPointString(gridPoint) + ", gltf: "+SoundUtil.toPointString(gridItemDto.getPointCrs()));
                gridItemList.add(gridItemDto);
            }

            faceItemDto.setGridList(gridItemList);
        }else{
            faceItemDto.setScopeList(new ArrayList<>());
            faceItemDto.setWidthSize(0);
            faceItemDto.setGridList(new ArrayList<>());
        }

        return faceItemDto;
    }

    //根据起止点获取网格数
    private int getWidthSize(float[] point1,float[] point2){
        log.info("----------- start width size -------------------------");
        log.info("point1 : "+point1[0] + "," + point1[1] + "," + point1[2]);
        log.info("point2 : "+point2[0] + "," + point2[1] + "," + point2[2]);
        //获取两点之间的距离
        double distance = SoundUtil.getDistance(SoundUtil.getPointBean(point1),SoundUtil.getPointBean(point2));
        log.info("distance : "+distance);
        //根据距离和预设的步长长度，获取网格数
        int widthSize = (int) Math.round(distance / Constant.STEP_LENGTH);
        log.info("widthSize : "+widthSize);
        log.info("----------- end width size -------------------------");
        return widthSize;
    }



    //将点列表转换为点对象列表
    private List<PointItemDto> getPointList(List<float[]> pointList,boolean isGltf){
        return pointList.parallelStream().map(point -> {
            PointItemDto pointItemDto = new PointItemDto();
            if(isGltf){
                float[] gltfPoint = SoundUtil.toGltfCrs(point);
                pointItemDto.setX(gltfPoint[0]);
                pointItemDto.setY(gltfPoint[1]);
                pointItemDto.setZ(gltfPoint[2]);
            }else{
                pointItemDto.setX(point[0]);
                pointItemDto.setY(point[1]);
                pointItemDto.setZ(point[2]);
            }
            return pointItemDto;
        }).collect(Collectors.toList());
    }
}
